package webdav

import (
	"embed"
	_ "embed"
	"fmt"
	"golang.org/x/net/webdav"
	"log"
	"net/http"
	"os"
	"strings"
	"sync"
)

//go:embed folder.html
var configFile embed.FS

func formatFileSize(size int64) string {
	const (
		B = 1 << (10 * iota)
		KB
		MB
		GB
		TB
		PB
		EB
	)

	switch {
	case size < KB:
		return fmt.Sprintf("%d B", size)
	case size < MB:
		return fmt.Sprintf("%.2f KB", float64(size)/float64(KB))
	case size < GB:
		return fmt.Sprintf("%.2f MB", float64(size)/float64(MB))
	case size < TB:
		return fmt.Sprintf("%.2f GB", float64(size)/float64(GB))
	case size < PB:
		return fmt.Sprintf("%.2f TB", float64(size)/float64(TB))
	case size < EB:
		return fmt.Sprintf("%.2f PB", float64(size)/float64(PB))
	default:
		return fmt.Sprintf("%.2f ZB", float64(size))
	}
}

var modelContent string
var once = sync.Once{}

func getFolderModel() string {
	once.Do(func() {
		//dir_model, open_err := os.ReadFile("folder.html")
		dir_model, open_err := configFile.ReadFile("folder.html")
		if open_err != nil {
			fmt.Println("打开目录页面模板失败", open_err)
			modelContent = ""
		}
		modelContent = string(dir_model)
		//fmt.Println(modelContent)
	})
	return modelContent
}

func (h *CloudFileSystem) handleGetDir(w http.ResponseWriter, r *http.Request, path string, ff webdav.File) (status int, err error) {
	fileInfos, err := ff.Readdir(0)
	if err != nil {
		return http.StatusForbidden, err
	}

	model := getFolderModel()
	model = strings.Replace(model, "###folder_path", path, -1)
	var file_list []string
	var folder_list []string
	for _, fileInfo := range fileInfos {
		//fmt.Println(fileInfo.Name())
		if fileInfo.IsDir() {
			a_html := "<a href=\"" + path + fileInfo.Name() + "/\">"
			a_content := fmt.Sprintf("%s%s/</a>  %s        -", a_html, fileInfo.Name(), fileInfo.ModTime().Format("2006-01-02 15:04:05"))
			folder_list = append(folder_list, a_content)
		} else {
			a_html := "<a href=\"" + path + fileInfo.Name() + "\">"
			a_content := fmt.Sprintf("%s%s</a>  %s     %s", a_html, fileInfo.Name(), fileInfo.ModTime().Format("2006-01-02 15:04:05"), formatFileSize(fileInfo.Size()))
			file_list = append(file_list, a_content)
		}
	}

	spr := ""
	if len(folder_list) > 0 {
		spr = "\n"
	}
	file_list_content := strings.Join(folder_list, "\n") + spr + strings.Join(file_list, "\n")
	w.Write([]byte(strings.Replace(model, "#alist", file_list_content, -1)))

	return http.StatusNoContent, nil
}

func (h *CloudFileSystem) handleVoiceList(w http.ResponseWriter, r *http.Request) (status int, err error) {
	// 处理请求 /voice_list
	ctx := r.Context()
	f, errFlag := h.OpenFile(ctx, "/我的音乐", os.O_RDONLY, 0)
	if errFlag != nil {
		log.Println(errFlag)
		h.handler.ServeHTTP(w, r)
		return
	}
	defer f.Close()
	fileInfos, err := f.Readdir(0)
	if err != nil {
		return http.StatusForbidden, err
	}

	var items []string
	for _, fileInfo := range fileInfos {
		if fileInfo.IsDir() {
			items = append(items, fmt.Sprintf("{\n\"name\": \"%s\",\n\"url\": \"/189/music_list_item/%s\"\n}", fileInfo.Name(), fileInfo.Name()))
		}
	}

	f2, errorFlag := h.OpenFile(ctx, "/voice", os.O_RDONLY, 0)
	if errorFlag != nil {
		h.handler.ServeHTTP(w, r)
		return
	}
	defer f2.Close()
	fileInfos, err = f2.Readdir(0)
	if err != nil {
		return http.StatusForbidden, err
	}
	for _, fileInfo := range fileInfos {
		if "player" == fileInfo.Name() || "m3u8_play" == fileInfo.Name() {
			continue
		}
		if fileInfo.IsDir() {
			items = append(items, fmt.Sprintf("{\n\"name\": \"%s\",\n\"url\": \"/189/voice_list_item/%s\"\n}", fileInfo.Name(), fileInfo.Name()))
		}
	}

	result := "[" + strings.Join(items, ",") + "]"
	w.Write([]byte(result))

	return http.StatusNoContent, nil
}

func (h *CloudFileSystem) handleMusicListItem(w http.ResponseWriter, r *http.Request, folderName string) (status int, err error) {
	// 处理请求 /189/music_list_item/{folder_name}
	ctx := r.Context()
	f, errFlag := h.OpenFile(ctx, "/我的音乐/"+folderName, os.O_RDONLY, 0)
	if errFlag != nil {
		log.Println(errFlag)
		w.Write([]byte("{\"error\": \"文件不存在\"}"))
		return
	}
	defer f.Close()

	fileInfos, err := f.Readdir(0)
	if err != nil {
		w.Write([]byte("{\"error\": \"文件不存在\"}"))
		return
	}

	var items []string
	for _, fileInfo := range fileInfos {
		if !fileInfo.IsDir() {
			items = append(items, fmt.Sprintf("{\n\"musicTime\": \"440\",\n\"artist\": \"我的音乐\",\n\"avatarURL\": \"avatar/wanghongnv.jpg\",\n\"musicURL\": \"/189/我的音乐/%s/%s\",\n\"musicAlbum\": \"%s\",\n\"musicName\": \"%s\"\n}", folderName, fileInfo.Name(), fileInfo.Name(), fileInfo.Name()))
		}
	}
	//reverseStringSlice(items)
	result := "[" + strings.Join(items, ",") + "]"

	w.Write([]byte(result))
	return http.StatusNoContent, nil
}

func (h *CloudFileSystem) handleVoiceListItem(w http.ResponseWriter, r *http.Request, folderName string) (status int, err error) {
	// 处理请求 /189/voice_list_item/{folder_name}
	ctx := r.Context()
	f, errFlag := h.OpenFile(ctx, "/voice/"+folderName, os.O_RDONLY, 0)
	if errFlag != nil {
		log.Println(errFlag)
		w.Write([]byte("{\"error\": \"文件不存在\"}"))
		return
	}
	defer f.Close()
	fileInfos, err := f.Readdir(0)
	if err != nil {
		w.Write([]byte("{\"error\": \"文件不存在\"}"))
		return
	}

	var items []string
	for _, fileInfo := range fileInfos {
		if fileInfo.IsDir() {
			items = append(items, fmt.Sprintf("{\n\"musicTime\": \"440\",\n\"artist\": \"我的音乐\",\n\"avatarURL\": \"avatar/wanghongnv.jpg\",\n\"musicURL\": \"/189/voice/%s/%s/index.m3u8\",\n\"musicAlbum\": \"%s\",\n\"musicName\": \"%s\"\n}", folderName, fileInfo.Name(), fileInfo.Name(), fileInfo.Name()))
		}
	}
	//reverseStringSlice(items)
	result := "[" + strings.Join(items, ",") + "]"

	w.Write([]byte(result))

	return http.StatusNoContent, nil
}

//func reverseStringSlice(slice []string) []string {
//	// 反转字符串切片
//	for i := 0; i < len(slice)/2; i++ {
//		opp := len(slice) - 1 - i
//		slice[i], slice[opp] = slice[opp], slice[i]
//	}
//	return slice
//}
